package com.baike.controller;


import com.alibaba.fastjson.JSON;
import com.baike.data.RedisName;
import com.baike.data.Result;
import com.baike.em.ConstantEnum;
import com.baike.entity.TbCategories;
import com.baike.service.impl.TbCategoriesServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author lbs
 * @since 2021-10-30
 */
@RestController
@RequestMapping("categoriesController")
@Api("课程管理实例")
public class TbCategoriesController {

    @Autowired
    private TbCategoriesServiceImpl categoriesService;
    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping
    @ApiOperation("增加课程分类数据")
    @ApiImplicitParam(value = "课程分类实体类数据",name = "categories",required = true,paramType = "body")
    public Result postCategoryies(@RequestBody TbCategories categories){
        StringRedisSerializer serializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jack = new Jackson2JsonRedisSerializer(Object.class);
        redisTemplate.setHashKeySerializer(serializer);
        redisTemplate.setKeySerializer(serializer);
        redisTemplate.setValueSerializer(jack);
        redisTemplate.setHashValueSerializer(jack);


        // 参数非空判断
        if(Objects.nonNull(categories)){
            boolean b = categories.insert();
           // boolean b = categoriesService.save(categories);
            System.out.println(categories.getCategoriesId());
            //数据添加状态判断
            if(b){
                //添加数据成功 删除 redis 原有的缓存
                if(redisTemplate.hasKey(RedisName.REDIS_CATE_PARENT_NAME)){
                    redisTemplate.boundHashOps(RedisName.REDIS_CATE_PARENT_NAME).delete(RedisName.REDIS_CATE_BOY_NAME + categories.getCategoriesParentId());
                }
                return Result.build(ConstantEnum.SUCCESS);
            }else {
                return Result.build(ConstantEnum.ERROR);
            }
        }
        return Result.build(ConstantEnum.NULL_DATA_PARAMETER);


    }

    @DeleteMapping
    @ApiOperation("课程分类数据删除")
    @ApiImplicitParam(value = "课程分类实体类id数组",name = "ids",required = true,paramType = "query")
    public Result delCategoryies(@RequestParam("ids")Integer[] ids){
        StringRedisSerializer serializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jack = new Jackson2JsonRedisSerializer(Object.class);
        redisTemplate.setHashKeySerializer(serializer);
        redisTemplate.setKeySerializer(serializer);
        redisTemplate.setValueSerializer(jack);
        redisTemplate.setHashValueSerializer(jack);


        // 将传过来的id进行删除   因为是二级目录 删除 当前id 以及 父级id
        // 数据判断
        if(Objects.nonNull(ids)){
            LambdaQueryWrapper<TbCategories> wrapper = Wrappers.<TbCategories>lambdaQuery().in(TbCategories::getCategoriesId, Arrays.asList(ids))
                    .or().in(TbCategories::getCategoriesParentId, Arrays.asList(ids));
            boolean b = categoriesService.remove(wrapper);
            if (b){
                // 删除 redis 缓存
                redisTemplate.delete(RedisName.REDIS_CATE_PARENT_NAME);
                return  Result.build(ConstantEnum.SUCCESS);
            }else {
                return Result.build(ConstantEnum.ERROR);
            }
        }
        return Result.build(ConstantEnum.ERROR);

    }

    @PutMapping
    @ApiOperation("分类实体类数据修改")
    @ApiImplicitParam(value = "分类实体类数据",name = "categories",required = true,paramType = "body")
    public Result putCategoryies(@RequestBody TbCategories categories){
        StringRedisSerializer serializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jack = new Jackson2JsonRedisSerializer(Object.class);
        redisTemplate.setHashKeySerializer(serializer);
        redisTemplate.setKeySerializer(serializer);
        redisTemplate.setValueSerializer(jack);
        redisTemplate.setHashValueSerializer(jack);


        // 非空判断
        if(Objects.nonNull(categories)){

            boolean b = categoriesService.updateById(categories);
            // 修改状态判断
            if(b){
                // 删除 redis 缓存
                redisTemplate.boundHashOps(RedisName.REDIS_CATE_PARENT_NAME).delete(RedisName.REDIS_CATE_BOY_NAME + categories.getCategoriesParentId());
                return Result.build(ConstantEnum.SUCCESS);
            }else {
                return Result.build(ConstantEnum.ERROR);
            }
        }
        return Result.build(ConstantEnum.NULL_DATA_PARAMETER);
    }

    @GetMapping
    @ApiOperation("根据id查询分类数据")
    @ApiImplicitParam(value = "课程分类实体类数据id",name = "id",required = true,paramType = "query")
    public Result findCategoryiesById(@RequestParam("id")Integer id){
        // 非空判断
        if(Objects.nonNull(id)){
            TbCategories categories = categoriesService.getById(id);
            // 数据获取判断
            if(Objects.nonNull(categories)){
                return Result.build(ConstantEnum.SUCCESS).setResult(categories);
            }
            return Result.build(ConstantEnum.NULL_DATA);
        }
        return Result.build(ConstantEnum.NULL_DATA_PARAMETER);
    }

    @PostMapping("findByPid")
    @ApiOperation("根据传来的pid 查子级  一级目录的pid都为0  ")
    @ApiImplicitParam(value = "课程分类实体类数据id",name = "pid",required = true,paramType = "query")
    public  Result findByPid(@RequestParam("pid")Integer pid){

        StringRedisSerializer serializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jack = new Jackson2JsonRedisSerializer(Object.class);
        redisTemplate.setHashKeySerializer(serializer);
        redisTemplate.setKeySerializer(serializer);
        redisTemplate.setValueSerializer(jack);
        redisTemplate.setHashValueSerializer(jack);

        // 非空判断
        if(Objects.nonNull(pid)){
            BoundHashOperations hashOps = redisTemplate.boundHashOps(RedisName.REDIS_CATE_PARENT_NAME);
            Boolean b = hashOps.expire(1, TimeUnit.DAYS);
            //判断是否有 redis 缓存
                if(hashOps.hasKey(RedisName.REDIS_CATE_BOY_NAME + pid)){
                    // 取出redis数据
                    String listStr = (String) hashOps.get(RedisName.REDIS_CATE_BOY_NAME + pid);
                    List<TbCategories> categoriesList = JSON.parseArray(listStr,TbCategories.class);
                    return Result.build(ConstantEnum.SUCCESS).setResult(categoriesList);
                }else {
                    //从数据库获取数据
                    LambdaQueryWrapper<TbCategories> wrapper = Wrappers.<TbCategories>lambdaQuery().eq(TbCategories::getCategoriesParentId, pid);
                    List<TbCategories> list = categoriesService.list(wrapper);
                    if(list.size() > 0){
                        //放入缓存
                        hashOps.put(RedisName.REDIS_CATE_BOY_NAME + pid,JSON.toJSON(list).toString());
                        return Result.build(ConstantEnum.SUCCESS).setResult(list);
                    }
                    return Result.build(ConstantEnum.NULL_DATA);

                }
        }
        return Result.build(ConstantEnum.NULL_DATA_PARAMETER);
    }

}
